<?php
namespace ITSociaal\Themes\Houtgrutter\Laura;

use ITSociaal\Themes\Houtgrutter\Util as UtilBase;
use ReflectionClass;
use ReflectionMethod;
use WP_Query;

class Util extends UtilBase
{
	/**
	 * Iterate over posts in a WP_Query object.
	 *
	 * Does not execute any actions!
	 *
	 * @param WP_Query $wpq WP_Query object to iterate
	 *
	 * @return \Iterator yields posts (if any)
	 */
	public function generatePostsFromWpQuery(WP_Query $wpq)
	{
		$posts = $wpq->posts;
		reset($posts);
		foreach ($posts as $post) {
			yield $post;
		}
	}

	/**
	 * Create dummy post object compatible with get_post
	 *
	 * @return \stdClass Only minimal properties present
	 */
	public function createEmptyPost()
	{
		return (object)[
			"ID" => 0,
			"filter" => "raw",
			"post_content" => "",
			"post_title" => "",
		];
	}

	/**
	 * List methods in $class
	 *
	 * @param string|object $class
	 * @param boolean       $protected whether to include protected methods
	 *
	 * @return string[]
	 */
	public function getMethodsFromClass($class, $protected=false)
	{
		return array_map(
			function($method) {
				return $method->name;
			},
			(new ReflectionClass($class))
				->getMethods(
					ReflectionMethod::IS_PUBLIC | (
						intval(boolval($protected)) *
						ReflectionMethod::IS_PROTECTED
					)
				)
		);
	}

	/**
	 * Return subset of string array with matching prefix
	 *
	 * @param string[] $strings
	 * @param string   $prefix
	 *
	 * @return string[] only strings that begin with $prefix
	 */
	public function filterPrefix(array $strings, $prefix)
	{
		return array_values(array_filter(
			$strings,
			function($value) use ($prefix) {
				return strpos($value, $prefix) === 0;
			}
		));
	}

	/**
	 * Return array callables from list of methods on object
	 *
	 * @param object   $object
	 * @param string[] $methods
	 *
	 * @return array[] callables
	 */
	public function makeCallables($object, $methods)
	{
		return array_map(
			function($method) use ($object) {
				// This can somehow crash PHP with xdebug enabled
				return [$object, $method];
			},
			$methods
		);
	}

	/**
	 * Return list of callables for methods with a given prefix in $object
	 *
	 * @param object  $object
	 * @param string  $prefix
	 * @param boolean $protected
	 *
	 * @return array[] callables
	 */
	public function getCallablesFromPrefixedMethods(
		$object, $prefix, $protected=false
	) {
		return $this->makeCallables(
			$object,
			$this->filterPrefix(
				$this->getMethodsFromClass($object, $protected),
				$prefix
			)
		);
	}
}

/* vi:set ts=4 sw=4 noet: */
